package com.mitcub.panda.utils;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @项目名称: panda
 * @类名称: TreeUtils
 * @类描述:
 * @作者: tangloong
 * @创建时间: 2021/11/12 12:43
 */
public class TreeUtils {

    //Java反射机制，获取对象的属性和值（包括所有父类）
    private static List<Field> getAllField(Object bean) {
        Class clazz = bean.getClass();
        List<Field> fields = new ArrayList<>();
        while (clazz != null) {
            fields.addAll(new ArrayList<>(Arrays.asList(clazz.getDeclaredFields())));
            clazz = clazz.getSuperclass();
        }
        return fields;
    }
    //Java反射机制，获取对象的指定属性
    private static Field getFiled(Class<?> clazz,String filedName){
        Field field = null;
        while (clazz != null && field == null) {
            try {
                field = clazz.getDeclaredField(filedName);
            }catch (Exception e){
            //    System.out.println(e.toString());
            }
            clazz = clazz.getSuperclass();
        }
        return field;
    }

    public static  <T> List<T> getTreeList(List<T> t,Integer pid){
        List<T> list = new ArrayList<>();
        for (int i = 0; i < t.size(); i++) {
            T item = t.get(i);
            Class<?> itemClass = item.getClass();
            //Field idField = itemClass.getDeclaredField("id"); //该方法能获取到本类的所有属性，包括private，protected和public，但不能获取到继承的父类的属性
            //Field idField = itemClass.getField("id");//既能获取本类的属性也能得到父类的属性，但仅仅能获取public修饰的字段
            Field idField = getFiled(itemClass,"id");
            Class<?> type = idField.getType();
            idField.setAccessible(true);
            try {
                if (type.getTypeName().equals("java.lang.String")) {
                    String itemId = idField.get(item).toString();
                    Field pidField = itemClass.getDeclaredField("pid");
                    pidField.setAccessible(true); //这里只能获取到private的字段，但并不能访问该private字段的值,除非加上setAccessible(true)
                    String itemPid = pidField.get(item).toString();
                    if (itemPid.equals(pid + "")) {
                        Field childField = itemClass.getDeclaredField("children");
                        childField.setAccessible(true); //这里只能获取到private的字段，但并不能访问该private字段的值,除非加上setAccessible(true)
                        childField.set(item, getTreeList(t, (Integer.valueOf(itemId))));
                        list.add(item);
                    }
                } else {
                    Integer itemId = (Integer) idField.get(item);
                    Field pidField = itemClass.getDeclaredField("pid");
                    pidField.setAccessible(true);
                    Integer itemPid = (Integer) pidField.get(item);
                    if (itemPid == pid) {
                        Field childField = itemClass.getDeclaredField("children");
                        childField.setAccessible(true);
                        childField.set(item, getTreeList(t, itemId));
                        list.add(item);
                    }
                }
            }catch (Exception e){

            }
        }
        return list;
    }

}
